// ------------------------------------------
// SpySatellite.cs
// ------------------------------------------

datablock TurretData(DeployedSpySatellite) : TurretDamageProfile
{
   shapeFile = "turret_indoor_deployc.dts";
   heatSignature = 0.0;
   deployedObject = true;
   primaryAxis = revzaxis;
   className = DeployedTurret;
   mass = 0.7;
   maxDamage = 1.0;
   destroyedLevel = 1.0;
   disabledLevel = 1.0;
   explosion      = CameraGrenadeExplosion;
   repairRate = 0;
   heatSignature = 0.0;
   deployedObject = true;
   thetaMin = 120;
   thetaMax = 180;
   thetaNull = 180;
   primaryAxis = zaxis;
   isShielded = false;
   energyPerDamagePoint = 1;
   maxEnergy = 1000;
   rechargeRate = 1.0;
   barrel = SpySatelliteBarrel;
   canControl = true;
   canObserve = true;
   cmdCategory = "DSupport";
   cmdIcon = CMDCameraIcon;
   cmdMiniIconName = "commander/MiniIcons/com_camera_grey";
   targetNameTag = 'command';
   targetTypeTag = 'Satellite';
   sensorData = CameraSensorObject;
   sensorRadius = CameraSensorObject.detectRadius;
   firstPersonOnly = true;
   renderWhenDestroyed = false;
   observeParameters = "0.5 4.5 4.5";
   debrisShapeName = "debris_generic_small.dts";
   debris = TurretDebrisSmall;
};

datablock TurretImageData(SpySatelliteBarrel)
{
   shapeFile = "turret_muzzlepoint.dts";
   item      = SpySatelliteBarrel;

   // Turret parameters
   activationMS      = 150;
   deactivateDelayMS = 300;
   thinkTimeMS       = 150;
   degPerSecTheta    = 580;
   degPerSecPhi      = 960;
   attackRadius      = 1;

   // State transitions
   stateName[0]                     = "Activate";
   stateTransitionOnTimeout[0]      = "ActivateReady";
   stateTimeoutValue[0]             = 0.5;
   stateSequence[0]                 = "Activate";

   stateName[1]                     = "ActivateReady";
   stateTransitionOnLoaded[1]       = "Ready";
   stateTransitionOnNoAmmo[1]       = "NoAmmo";

   stateName[2]                     = "Ready";
   stateTransitionOnTriggerDown[2]  = "Fire";

   stateName[3]                     = "Fire";
   stateTransitionOnTimeout[3]      = "Reload";
   stateTimeoutValue[3]             = 0.5;
   stateFire[3]                     = true;
   stateAllowImageChange[3]         = false;
   stateSequence[3]                 = "Fire";
   stateScript[3]                   = "onFire";

   stateName[4]                     = "Reload";
   stateTransitionOnTimeout[4]      = "Ready";
   stateTimeoutValue[4]             = 0.5;
   stateAllowImageChange[4]         = false;
};

function SpySatelliteBarrel::onFire(%data,%obj,%slot)
{
   %range = 1000; //Max range It can move.
   %rot = rotFromTransform(%obj.getTransform());
   %muzzlePos = %obj.getMuzzlePoint(%slot);
   %muzzleVec = %obj.getMuzzleVector(%slot);
   %endPos    = VectorAdd(%muzzlePos, VectorScale(%muzzleVec, %range));
   %damageMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType |
                  $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType |
                  $TypeMasks::SensorObjectType | $TypeMasks::TurretObjectType |
                  $TypeMasks::InteriorObjectType;

   %terrain = ContainerRayCast(%muzzlePos, %endPos, $TypeMasks::TerrainObjectType, %obj);
   %message = "";
   if (%terrain)
   {
      %xy = getWords(%terrain, 1, 2);
      %z = getWord(%terrain, 3);
      %pos = %xy SPC %z + 200;
      %mask =    ($TypeMasks::VehicleObjectType     | $TypeMasks::MoveableObjectType   |
                  $TypeMasks::StaticShapeObjectType |
                  $TypeMasks::ForceFieldObjectType  | $TypeMasks::ItemObjectType       |
                  $TypeMasks::PlayerObjectType      | $TypeMasks::TurretObjectType);
      InitContainerRadiusSearch( %pos, 2, %mask );
      %test = containerSearchNext();
      if (%test)
         %message = "Can\'t reposition the satellite. Trajectory Blocked";
      else
      {
         %obj.setTransform(%pos SPC %rot);
      }
   }
   else
      %message = "Trajectory not understood. Reenter.";
   if (%message !$= "")
      messageClient(%obj.client, 'msgBlocked', %message);
}


datablock ShapeBaseImageData(SpySatelliteDeployableImage)
{
   shapeFile = "pack_deploy_sensor_pulse.dts";
   item = SpySatelliteDeployable;
   mountPoint = 1;
   offset = "0 0 0";
   deployed = DeployedSpySatellite;

   stateName[0] = "Idle";
   stateTransitionOnTriggerDown[0] = "Activate";

   stateName[1] = "Activate";
   stateScript[1] = "onActivate";
   stateTransitionOnTriggerUp[1] = "Idle";
   deploySound = SpySatelliteDeploySound;

   maxDepSlope = 40;
   emap = true;
   heatSignature = 0;

   minDeployDis                       =  0.1;
   maxDeployDis                       =  15.0;  //meters from body
};

datablock ItemData(SpySatelliteDeployable)
{
   className = Pack;
   catagory = "Deployables";
   shapeFile = "pack_deploy_sensor_pulse.dts";
   mass = 2.0;
   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 1;
   rotate = false;
   image = "SpySatelliteDeployableImage";
   pickUpName = "a command satellite pack";

   computeCRC = true;
   emap = true;
};

function DeployedSpySatellite::onTrigger(%data, %obj, %trigger, %state)
{
   switch (%trigger)
   {
      case 0:
	   if(%state)
		%obj.setImageTrigger(0, true);
	   else
		%obj.setImageTrigger(0, false);
      case 2:
         if(%state) 
         {
            %obj.getDataBlock().playerDismount(%obj);
         }
      case 4:
         if(%state)
         {
            if(getSimTime() < $NoArtilleryTime[%obj.team])
            {
               messageClient(%obj.client, "", "\c2Unable to call artillery. You must wait "@$NoArtilleryTime[%obj.team] - getSimTime()@".");
               return;
            }

            %eye = %obj.getMuzzleVector(0);
            %pos = %obj.getMuzzlePoint(0);
            %masks = $TypeMasks::StaticShapeObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType;
            %search = containerRayCast(%pos, vectorAdd(%pos,vectorScale(%eye,2000)), %masks, %obj);
            if(!%search)
            {
               messageClient(%obj.client, "", "\c2Unable to call artillery. You must call at a valid spot.");
               return;
            }

            %dest = posFromRaycast(%search);
            %nade = new GrenadeProjectile() {
               dataBlock        = BeaconSmokeGrenadeProj;
               initialDirection = "0 0 -1";
               initialPosition  = VectorAdd(%dest, "0 0 "@getRandom(350, 450));
               sourceObject     = %obj;
               sourceSlot       = 0;
            };

            for(%i = 0; %i < 3; %i++)
            {
               %p = new GrenadeProjectile() {
                  dataBlock        = BeaconSmokeGrenadeProj;
                  initialDirection = "0 0 -1";
                  initialPosition  = VectorAdd(%dest, getRandom(10, 30) SPC getRandom(10, 30) SPC getRandom(350, 450));
                  sourceObject     = %obj;
                  sourceSlot       = 0;
               };

               MissionCleanup.add(%p);
               %p.schedule(60000, "delete");
            }

            MissionCleanup.add(%nade);
            %nade.schedule(60000, "delete");

            %otherteam = (%obj.team == 1 ? 2 : 1);
            messageTeam(%obj.team, "", "\c2Your team's commander has called an artillery strike.");

            schedule(200, 0, "messageAll", "MsgAll", "~wfx/weapons/spinfusor_impact_UW.wav");
            schedule(800, 0, "messageAll", "MsgAll", "~wfx/weapons/spinfusor_impact_UW.wav");
            schedule(1000, 0, "messageAll", "MsgAll", "~wfx/weapons/spinfusor_impact_UW.wav");
            schedule(1200, 0, "messageAll", "MsgAll", "~wfx/weapons/spinfusor_impact_UW.wav");
            schedule(1700, 0, "messageAll", "MsgAll", "~wfx/weapons/spinfusor_impact_UW.wav");
            schedule(1900, 0, "messageAll", "MsgAll", "~wfx/weapons/spinfusor_impact_UW.wav");
            schedule(10000, 0, "JTLMeteorStorm", %nade, 0, 70, getRandom(15, 25), 800, 2500, artillerybarrelshot, GrenadeProjectile, 0, 0, 0, 0, 0, 0, 0, 0, %dest, 0); // NOTE! We must give the grenade enough time to hit the ground!
            $NoArtilleryTime[%obj.team] = getSimTime() + 320000;
         }
   }
   if (%trigger == 3){ //rightclick select
	if(%state){
	   %eye = %obj.getMuzzleVector(0);
	   %pos = %obj.getMuzzlePoint(0);
	   %search = containerRayCast(%pos,vectorAdd(%pos,vectorScale(%eye,2000)), $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::TerrainObjectType, %obj);
	   if(%search){
		%srcobj = firstWord(%search);
		if(%srcobj.getDatablock().numMountPoints > 0){
		   if(%srcobj.team == %obj.team){
			%releaseselected = 1;
			%newselected = %srcobj;
		   }
		   else
			%callTarget = %srcobj;
		}
		else{
		   %srcpos = posFromRaycast(%search);
		   InitContainerRadiusSearch(%srcpos,10,$TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType);
		   while ((%TObject = containerSearchNext()) != 0 && %valid != 1){
			if(%TObject.team == %obj.team){
			   %releaseselected = 1;
			   %newselected = %TObject;
			   %valid = 1;
			}
			else if(%srcobj.team != 0 && %srcobj.team !$= ""){
			   %callTarget = %TObject;
			   %valid = 1;
			}
			else{
//			   %releaseselected = 1;
//			   %valid = 1;
			}
		   }
		}
		if(%releaseselected == 1){
		   if(isObject(%obj.selected)){
			if(%obj.selected.getDatablock().className $= "Armor"){
			   messageClient(%obj.selected.client, 'MgsClient', "\c2Continue on Soldier.");
			   %obj.selected = "";
			}
			else if(%obj.selected.getDatablock().numMountPoints > 0){
			   for(%i = 0; %i < %obj.selected.getDatablock().numMountPoints; %i++){
				if(%seat[%i] = %obj.selected.getMountNodeObject(%i))
				   messageClient(%seat[%i].client, 'MgsClient', "\c2Continue on Soldier.");
				
			   }
			   %obj.selected = "";
			}
		   }
		   if(isObject(%newselected)){
			if(%newselected.getDatablock().className $= "Armor"){
			   messageClient(%newselected.client, 'MgsClient', "\c2Listen up soldier.");
			   %obj.selected = %newselected;
			   messageClient(%obj.getControllingClient(), 'MgsClient', "\c2Player selected.");
			}
			else if(%newselected.getDatablock().numMountPoints > 0){
			   for(%i = 0; %i < %newselected.getDatablock().numMountPoints; %i++){
				if(%seat[%i] = %newselected.getMountNodeObject(%i))
				   messageClient(%seat[%i].client, 'MgsClient', "\c2Listen up soldier.");
			   }
			   %obj.selected = %newselected;
			   messageClient(%obj.getControllingClient(), 'MgsClient', "\c2Vehicle selected.");
			}
			else{
			   messageClient(%obj.getControllingClient(), 'MgsClient', "\c2Object selected.");
			   %obj.selected = %newselected;
			}
		   }
		}
		if(isObject(%calltarget)){
		   if(%obj.selected.getDatablock().className $= "Armor"){
			messageClient(%obj.selected.client, 'MgsClient', "\c2Attack this target.");
			%calltarget.commandAttachBeacon();
		   }
		   else if(%obj.selected.getDatablock().numMountPoints > 0){
			for(%i = 0; %i < %obj.selected.getDatablock().numMountPoints; %i++){
			   if(%seat[%i] = %obj.selected.getMountNodeObject(%i)){
				messageClient(%seat[%i].client, 'MgsClient', "\c2Attack this target.");
				%calltarget.commandAttachBeacon();
			   }
			}
		   }
		}
	   }
	}
   }
}

function SimObject::CommandAttachBeacon(%obj){
   if(isObject(%obj.enemyBeacon))
	%obj.enemyBeacon.delete();
   if (%obj.team == 1)
      %team = 2;
   else
      %team = 1;

   %beacon = new BeaconObject(){
      datablock = SubBeacon;
	beaconType = "enemy";
	position = %obj.getWorldBoxCenter();
   };
   %beacon.team = %team;
   %beacon.owner = %obj;
   %beacon.setTarget(%team);
   %obj.mountObject(%beacon, 4);
   %obj.enemyBeacon = %beacon;
   MissionCleanup.add(%beacon);
   %beacon.schedule(15000,"delete");

   %wa=new Waypoint() {
	position = %obj.getWorldBoxCenter();
	rotation = "1 0 0 0";
	dataBlock = "WayPointMarker";
	team = %team;
	name = "Attack this target.";
   };
   MissionCleanup.add(%wa);
   %wa.schedule(5000,"delete");
}

function SpySatelliteDeployable::onPickup(%this, %obj, %shape, %amount)
{
   // created to prevent console errors
}

function SpySatelliteDeployableImage::testObjectTooClose(%item)
{
   %xy = getWords(%item.surfacePt, 0, 1);
   %z = getWord(%item.surfacePt, 2);
   %z += 200;
   %item.surfacePt = %xy SPC %z;
   %item.surfaceNrm = "0 0 -1";
   %mask =    ($TypeMasks::VehicleObjectType     | $TypeMasks::MoveableObjectType   |
               $TypeMasks::StaticShapeObjectType |
               $TypeMasks::ForceFieldObjectType  | $TypeMasks::ItemObjectType       |
               $TypeMasks::PlayerObjectType      | $TypeMasks::TurretObjectType);
   InitContainerRadiusSearch( %item.surfacePt, $MinDeployDistance, %mask );
   %test = containerSearchNext();
   return %test;
}

function SpySatelliteDeployableImage::onDeploy(%item, %plyr, %slot)
{
   %deplObj = Parent::onDeploy(%item, %plyr, %slot);
   %deplObj.setCloaked(true);
   %deplObj.setPassiveJammed(true);
}

function DeployedSpySatellite::onDestroyed(%this, %obj, %prevState)
{
	if (%obj.isRemoved)
		return;
	if ($Host::InvincibleDeployables != 1 || %obj.damageFailedDecon) {
		%obj.isRemoved = true;
		$TeamDeployedCount[%obj.team, SpySatelliteDeployable]--;
		remDSurface(%obj);
		%obj.schedule(500, delete);
	}
	Parent::onDestroyed(%this, %obj, %prevState);
}